package org.example.admin.aop;

import org.apache.ibatis.annotations.Param;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.admin.annotation.OperationLog;
import org.example.admin.mapper.ProcessLogMapper;
import org.example.entity.ProcessLog;
import org.example.entity.UserSystem;
import org.springframework.stereotype.Controller;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

//利用AOP 将操作信息写入
@Controller
@Aspect
public class ProcessAdvisor {

    private ProcessLogMapper processLogMapper;

    public ProcessAdvisor(ProcessLogMapper processLogMapper){
        this.processLogMapper= processLogMapper;
    }

    /**
     * 在进入要操作的方法前，得先进入这个方法
     * AOP原理
     * @param jop
     */
    @Before(value = "@annotation(org.example.admin.annotation.OperationLog)")
    public void processBefore(JoinPoint jop){
        //获取方法的签名
        MethodSignature MethodSignature = (MethodSignature)jop.getSignature();
        //获取方法
        Method method = MethodSignature.getMethod();

        //获取注解
        OperationLog proccessInfo = method.getAnnotation(OperationLog.class);

        //登录用户
        ProcessLog pl = new ProcessLog();
        //添加依赖，拿到ActionContext来取存储在session的信息
//        ActionContext context = ActionContext.getContext();
//        Map params = context.getParameters();

//        UserSystem userSys = (UserSystem) params.get("userSession");

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserSystem userSys = (UserSystem)request.getSession().getAttribute("userSession");


        pl.setId(userSys.getId());
        pl.setUName(userSys.getUserName());
//        pl.setId(1);
//        pl.setUName("yang");
        pl.setPCreateDate(new Date());

        //获取操作的信息
        String value = proccessInfo.value();

        //将操作信息添加
        pl.setProcessInfo(value);

        //获取是否需要将这方法写进数据库库中的参数 false（默认） ：不写进 true:写进
        boolean b = proccessInfo.requireParamInfo();


        if (b){
            //获取方法中的所有参数
            //[a, b]  //获取所有的请求的参数  add(int a, int b) add(3, 4);
            Parameter[] parameters = method.getParameters();

            //方法中的调用参数的具体值 如： [3, 4]
            Object[] args = jop.getArgs();

            StringBuffer buffer = new StringBuffer();

            //赋值
            for (int i = 0; i < parameters.length; i++) {
               buffer.append( parameters[i].getName())
                       .append("=")
                       .append(args[i]).
                       append(";");
            }
            pl.setPDetail(buffer.toString());
        }
            //写入数据库
            processLogMapper.insertProcessLog(pl);
    }
}
